use cmsis_rtos2_rs::static_mem::Mutex;
use periph_utils::GpioConfig;
use periph_utils::stm32f1;
use utils::BitSet;



#[derive(GpioConfig)]
#[gpio(init = "gpio_init", 
    io(name = "pl", io = "PB3", mode = "OUT_PP", set, reset),
    io(name = "sck", io = "PB4", mode = "OUT_PP", set, reset),
    io(name = "q7", io = "PB5", mode = "IN_FLOAT", read),
    io(name = "leak", io = "PC12", mode = "IN_FLOAT", read), // 漏水
    io(name = "waste", io = "PC13", mode = "IN_FLOAT", read), // 废水
)]
struct Pin;

static MUTEX: Mutex = Mutex::uninit();

pub unsafe fn init() {
    Pin::gpio_init();
    MUTEX.init_once("sensor");
}

fn read() -> u16 {
    MUTEX.free(read_impl)
}

pub fn is_drop_sw1() -> bool {
    read().is_set(0)
}

pub fn is_drop_sw2() -> bool {
    read().is_set(1)
}

pub fn is_drop_sw3() -> bool {
    read().is_set(2)
}

pub fn is_film_sw() -> bool {
    !read().is_set(4)
}

pub fn is_film_checked() -> bool {
    !read().is_set(5)
}

pub fn is_cut_top() -> bool {
    read().is_set(8)
}

pub fn is_cut_bottom() -> bool {
    read().is_set(9)
}

pub fn is_cut_checked() -> bool {
    read().is_set(10)
}

pub fn is_cup_checked() -> bool {
    read().is_set(11)
}

pub fn is_drop_checked1() -> bool {
    read().is_set(13)
}

pub fn is_drop_checked2() -> bool {
    read().is_set(14)
}

pub fn is_drop_checked3() -> bool {
    read().is_set(15)
}

pub fn is_leak() -> bool {
    Pin::leak_read()
}

pub fn is_waste_checked() -> bool {
    Pin::waste_read()
}

fn read_impl() -> u16 {
    let mut value: u16 = 0;
    Pin::pl_reset();
    Pin::pl_set();
    for _ in 0..16 {
        value <<= 1;
        if Pin::q7_read() {
            value |= 0x01;
        }
        Pin::sck_set();
        Pin::sck_reset();
    }
    value
}








